package co.gov.medellin.ssti.sub.paoyer.administration.dao;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.sql.PreparedStatement;

import co.gov.medellin.ssti.sub.paoyer.administration.model.vo.UserGroupVO;

/**
 * DAO para crear, consultar , borrar y actualizar registros en la tabla
 * TCS_GRUPO_USUARIO.
 * 
 * @author Rene.Rangel@consultsoft.com
 * @version 1.0
 */

public class UserGroupDAO {
	/**
	 * Conexion a la base de datos.
	 */
	private Connection conn = null;

	/**
	 * Constructor que inicializa la conexion con la base de datos.
	 * 
	 * @param conn
	 *            Conexion con la base de datos.
	 */

	public UserGroupDAO(Connection conn) {
		this.conn = conn;
	}

	/**
	 * Consulta un grupo de registros de la tabla TCS_GRUPO_USUARIO a partir de
	 * las condiciones que vienen en el Value Object
	 * 
	 * @param UserGroupVO
	 *            Value Object con las condiciones a tener encuenta.
	 * 
	 * @return Collection Arreglo de registros retornados de la consulta.
	 */
	public Collection<UserGroupVO> findUserGroupByCriterea(UserGroupVO criterea)
			throws SQLException {

		/**
		 * La busqueda se hace sobre la tabla Tcs_Grupo_Usuario , puesto que
		 * esta tabla no tiene llaves foraneas
		 * 
		 */

		String query = "SELECT " + "grus.codigo, " + "grus.nombre, "
				+ "grus.descripcion, "
				+ "TO_CHAR(grus.desde_vigencia,'yyyy-mm-dd') desde_vigencia, "
				+ "TO_CHAR(grus.hasta_vigencia,'yyyy-mm-dd') hasta_vigencia, "
				+ "grus.vigencia, " + "grus.indica_administrador, "
				+ "grus.indica_auditoria, "
				+ "grus.indica_manipulacion_bloques, "
				+ "grus.indica_bloqueo_registros, "
				+ "grus.clave_maximos_errores, " + "grus.clave_maximos_dias, "
				+ "grus.clave_min_dias_reusar, "
				+ "grus.clave_min_cambios_reuso "
				+ "FROM tcs_grupo_usuario grus ";

		String filters = "";

		// Filtro por Minimo Cambios Reusar
		if (criterea.getCode() != null
				&& !criterea.getCode().toString().equals("0")) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.codigo =" + criterea.getCode();
			} else {
				filters = filters + " AND grus.codigo =" + criterea.getCode();
			}
		}
		// Filtro por Nombre
		if ((criterea.getName() != null)
				&& !(criterea.getName().equalsIgnoreCase(""))
				&& criterea.getCode() != null
				&& !criterea.getCode().toString().equals("0")) {
			filters = filters + " UPPER(grus.nombre) LIKE '%"
					+ criterea.getName().toUpperCase() + "%' ";
		} else if ((criterea.getName() != null)
				&& !(criterea.getName().equalsIgnoreCase(""))
				&& criterea.getWebUserModif().equals("true")) {
			filters = filters + " UPPER(grus.nombre) LIKE '%"
					+ criterea.getName().toUpperCase() + "%' ";
		}

		// Filtro por Descripcion
		if ((criterea.getDescription() != null)
				&& !(criterea.getDescription().equalsIgnoreCase(""))) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " UPPER(grus.descripcion) LIKE '%"
						+ criterea.getDescription().toUpperCase() + "%' ";
			} else {
				filters = filters + " AND UPPER(grus.descripcion) LIKE '%"
						+ criterea.getDescription().toUpperCase() + "%' ";
			}
		}

		// Filtro por Control de Administrador
		if ((criterea.getAdminCtrlInd() != null)
				&& !(criterea.getAdminCtrlInd().equalsIgnoreCase(""))) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.indica_administrador = '"
						+ criterea.getAdminCtrlInd() + "'";
			} else {
				filters = filters + " AND grus.indica_administrador = '"
						+ criterea.getAdminCtrlInd() + "'";
			}
		}

		// Filtro por Control de Auditoria
		if ((criterea.getAuditCtrlInd() != null)
				&& !(criterea.getAuditCtrlInd().equalsIgnoreCase(""))) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.indica_auditoria = '"
						+ criterea.getAuditCtrlInd() + "'";
			} else {
				filters = filters + " AND grus.indica_auditoria = '"
						+ criterea.getAuditCtrlInd() + "'";
			}
		}

		// Filtro por Control de Bloqueo de Registros
		if ((criterea.getRecLockInd() != null)
				&& !(criterea.getRecLockInd().equalsIgnoreCase(""))) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.indica_bloqueo_registros = '"
						+ criterea.getRecLockInd() + "'";
			} else {
				filters = filters + " AND grus.indica_bloqueo_registros = '"
						+ criterea.getRecLockInd() + "'";
			}
		}

		// Filtro por Control de Bloques
		if ((criterea.getBlockCtrlInd() != null)
				&& !(criterea.getBlockCtrlInd().equalsIgnoreCase(""))) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.indica_manipulacion_bloques = '"
						+ criterea.getBlockCtrlInd() + "'";
			} else {
				filters = filters + " AND grus.indica_manipulacion_bloques = '"
						+ criterea.getBlockCtrlInd() + "'";
			}
		}

		// Filtro por Maximmo de Errores
		if (criterea.getKeyMaxErr() != null) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.clave_maximos_errores ="
						+ criterea.getKeyMaxErr();
			} else {
				filters = filters + " AND grus.clave_maximos_errores ="
						+ criterea.getKeyMaxErr();
			}
		}

		// Filtro por Maximmo de Dias Cambiar Clave
		if (criterea.getKeyMaxDays() != null) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.clave_maximos_dias ="
						+ criterea.getKeyMaxDays();
			} else {
				filters = filters + " AND grus.clave_maximos_dias ="
						+ criterea.getKeyMaxDays();
			}
		}

		// Filtro por Minimo Cambios Reusar
		if (criterea.getKeyMinChangesReuse() != null) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.clave_min_cambios_reuso ="
						+ criterea.getKeyMinChangesReuse();
			} else {
				filters = filters + " AND grus.clave_min_cambios_reuso ="
						+ criterea.getKeyMinChangesReuse();
			}
		}

		// Filtro por Minimo Dias Reusar
		if (criterea.getKeyMinDaysReuse() != null) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.clave_min_dias_reusar ="
						+ criterea.getKeyMinDaysReuse();
			} else {
				filters = filters + " AND grus.clave_min_dias_reusar ="
						+ criterea.getKeyMinDaysReuse();
			}
		}

		// Filtro por Vigencia
		if ((criterea.getUse() != null)
				&& !(criterea.getUse().equalsIgnoreCase(""))) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.vigencia = '" + criterea.getUse()
						+ "'";
			} else {
				filters = filters + " AND grus.vigencia = '"
						+ criterea.getUse() + "'";
			}
		}

		// Filtro por Desde Vigencia
		if ((criterea.getEffectiveFrom() != null)
				&& (!criterea.getEffectiveFrom().equals(""))) {
			if (filters.equals("")) {
				filters = filters + " grus.desde_vigencia = TO_DATE('"
						+ criterea.getEffectiveFrom() + "','yyyy-mm-dd')";
			} else {
				filters = filters + " AND grus.desde_vigencia = TO_DATE('"
						+ criterea.getEffectiveFrom() + "','yyyy-mm-dd')";
			}
		}

		// Filtro por Hasta Vigencia
		if ((criterea.getEffectiveUntil() != null)
				&& (!criterea.getEffectiveUntil().equals(""))) {
			if (filters.equalsIgnoreCase("")) {
				filters = filters + " grus.hasta_vigencia = TO_DATE('"
						+ criterea.getEffectiveUntil() + "','yyyy-mm-dd')";
			} else {
				filters = filters + " AND grus.hasta_vigencia = TO_DATE('"
						+ criterea.getEffectiveUntil() + "','yyyy-mm-dd')";
			}
		}

		// Filtro por grupo de usuario
		if (criterea.getName() != null && criterea.getCode() != null
				&& criterea.getCode().toString().equals("0")) {
			if (filters.equalsIgnoreCase("")) {
				if (criterea.getName().equals("SUPER USUARIO")) {
					filters = filters
							+ " ( grus.nombre in ('SUPER_USUARIO','ADMINISTRADOR_GENERAL','ADMINISTRADOR_SECRETARIA','ADMINISTRADOR_PROGRAMA','ADMINISTRADOR_SUBPROGRAMA','CONSULTAS','OPERADOR') OR grus.CAMPO_A1 = 'B' ) ";
				}
				if (criterea.getName().equals("ADMINISTRADOR GENERAL")) {
					filters = filters
							+ " ( grus.nombre in ('ADMINISTRADOR_GENERAL','ADMINISTRADOR_SECRETARIA','ADMINISTRADOR_PROGRAMA','ADMINISTRADOR_SUBPROGRAMA','CONSULTAS','OPERADOR') OR grus.CAMPO_A1 = 'B' ) ";
				}
				if (criterea.getName().equals("ADMINISTRADOR SECRETARIA")) {
					filters = filters
							+ " ( grus.nombre in ('ADMINISTRADOR_SECRETARIA','ADMINISTRADOR_PROGRAMA','ADMINISTRADOR_SUBPROGRAMA','CONSULTAS','OPERADOR') OR grus.CAMPO_A1 = 'B' ) ";
				}
				if (criterea.getName().equals("ADMINISTRADOR PROGRAMA")) {
					filters = filters
							+ " ( grus.nombre in ('ADMINISTRADOR_SUBPROGRAMA','CONSULTAS','OPERADOR') OR grus.CAMPO_A1 = 'B' ) ";
				}
				if (criterea.getName().equals("ADMINISTRADOR BENEFICIO")) {
					filters = filters
							+ " ( grus.nombre in ('CONSULTAS','OPERADOR') OR grus.CAMPO_A1 = 'B' ) ";
				}

			} else {
				if (criterea.getName().equals("SUPER USUARIO")) {
					filters = filters
							+ " AND ( grus.nombre in ('SUPER_USUARIO','ADMINISTRADOR_GENERAL','ADMINISTRADOR_PROGRAMA','ADMINISTRADOR_SUBPROGRAMA','CONSULTAS','OPERADOR') OR grus.CAMPO_A1 = 'B' ) ";
				}
				if (criterea.getName().equals("ADMINISTRADOR GENERAL")) {
					filters = filters
							+ " AND ( grus.nombre in ('ADMINISTRADOR_GENERAL','ADMINISTRADOR_PROGRAMA','ADMINISTRADOR_SUBPROGRAMA','CONSULTAS','OPERADOR') OR grus.CAMPO_A1 = 'B' ) ";
				}
				if (criterea.getName().equals("ADMINISTRADOR PROGRAMA")) {
					filters = filters
							+ " AND ( grus.nombre in ('ADMINISTRADOR_SUBPROGRAMA','CONSULTAS','OPERADOR') OR grus.CAMPO_A1 = 'B' ) ";
				}
				if (criterea.getName().equals("ADMINISTRADOR BENEFICIO")) {
					filters = filters
							+ " AND ( grus.nombre in ('CONSULTAS','OPERADOR') OR grus.CAMPO_A1 = 'B' ) ";
				}
			}
		}

		// Si hay filtros, entonces armar la clausula WHERE
		if (!filters.equals("")) {
			query = query + " where grus.campo_a1 IS NULL and" + filters;
		} else {
			query = query + " where grus.campo_a1 IS NULL";
		}

		query += " order by grus.nombre";

		// System.out.println(query);
		Statement stm = null;
		ResultSet rst = null;
		ArrayList<UserGroupVO> userGroups = new ArrayList<UserGroupVO>();

		stm = conn.createStatement();
		rst = stm.executeQuery(query);

		while (rst.next()) {
			UserGroupVO userGroup = new UserGroupVO();
			userGroup.setCode(new Long(rst.getLong("codigo")));
			userGroup.setName(rst.getString("nombre"));
			userGroup.setDescription(rst.getString("descripcion"));
			userGroup.setEffectiveFrom(rst.getString("desde_vigencia"));
			userGroup.setEffectiveUntil(rst.getString("hasta_vigencia"));
			userGroup.setUse(rst.getString("vigencia"));
			userGroup.setAdminCtrlInd(rst.getString("indica_administrador"));
			userGroup.setAuditCtrlInd(rst.getString("indica_auditoria"));
			userGroup.setBlockCtrlInd(rst
					.getString("indica_manipulacion_bloques"));
			userGroup.setRecLockInd(rst.getString("indica_bloqueo_registros"));
			userGroup.setKeyMaxErr(new Short(rst
					.getShort("clave_maximos_errores")));
			userGroup.setKeyMaxDays(new Short(rst
					.getShort("clave_maximos_dias")));
			userGroup.setKeyMinDaysReuse(new Short(rst
					.getShort("clave_min_dias_reusar")));
			userGroup.setKeyMinChangesReuse(new Short(rst
					.getShort("clave_min_cambios_reuso")));
			userGroups.add(userGroup);
		}

		stm.close();

		return userGroups;
	}

	/**
	 * Crea un nuevo registro en la tabla TCS_GRUPO_USUARIO.
	 * 
	 * @param UserGroupVO
	 *            Value Object con el registro que se va a Crear.
	 * 
	 * @return UserGroupVO Registro creado.
	 * 
	 */
	public UserGroupVO createUserGroup(UserGroupVO newUserGroup)
			throws SQLException {

		String strSQL = "";
		boolean result = false;
		PreparedStatement ps = null;
		strSQL = "" + "INSERT INTO paoyer.tcs_grupo_usuario ("
				+ "            codigo, nombre, descripcion, "
				+ "            usuario_crea, terminal_crea, "
				+ "            usuario_modifica, terminal_modifica) "
				+ "VALUES(paoyer.scs_gus.nextval,?,?,?,?,?,?)";

		ps = conn.prepareStatement(strSQL);
		ps.setString(1, newUserGroup.getName().toUpperCase());
		ps.setString(2, newUserGroup.getDescription().toUpperCase());
		// ps.setString(3, newUserGroup.getEffectiveFrom());
		// ps.setString(4, newUserGroup.getEffectiveUntil());
		// ps.setString(5, newUserGroup.getUse().toUpperCase());
		// ps.setString(6, newUserGroup.getAdminCtrlInd().toUpperCase());
		// ps.setString(7, newUserGroup.getAuditCtrlInd().toUpperCase());
		// ps.setString(8, newUserGroup.getBlockCtrlInd().toUpperCase());
		// ps.setString(9, newUserGroup.getRecLockInd().toUpperCase());

		/*
		 * if(newUserGroup.getKeyMaxErr()!=null) { ps.setLong(10,
		 * newUserGroup.getKeyMaxErr().longValue()); } else {
		 * ps.setNull(10,Types.NUMERIC); }
		 * if(newUserGroup.getKeyMaxDays()!=null) { ps.setLong(11,
		 * newUserGroup.getKeyMaxDays().longValue()); } else {
		 * ps.setNull(11,Types.NUMERIC); }
		 * if(newUserGroup.getKeyMinDaysReuse()!=null) { ps.setLong(12,
		 * newUserGroup.getKeyMinDaysReuse().longValue()); } else {
		 * ps.setNull(12,Types.NUMERIC); }
		 * if(newUserGroup.getKeyMinChangesReuse()!=null) { ps.setLong(13,
		 * newUserGroup.getKeyMinChangesReuse().longValue()); } else {
		 * ps.setNull(13,Types.NUMERIC); }
		 */
		ps.setString(3, newUserGroup.getWebUserCrea());
		ps.setString(4, "WEB=" + newUserGroup.getWebClientCrea());
		ps.setString(5, newUserGroup.getWebUserModif());
		ps.setString(6, "WEB=" + newUserGroup.getWebClientModif());
		result = ps.execute();

		ps.close();

		return newUserGroup;
	}

	/**
	 * Actualiza un registro en la tabla TCS_GRUPO_USUARIO por la llave
	 * primaria.
	 * 
	 * @param UserGroupVO
	 *            Value Object con el registro que se va a modificar.
	 * 
	 * @return UserGroupVO Registro modificado.
	 * 
	 */
	public UserGroupVO updateUserGroup(UserGroupVO userGroup)
			throws SQLException {

		String strSQL = "update paoyer.tcs_grupo_usuario "
				+ "set nombre = ?, "
				+ "descripcion = ?, "
				+
				// "desde_vigencia = ?, " +
				// "hasta_vigencia = ?, " +
				// "vigencia = ?, " +
				// "indica_administrador = ?, " +
				// "indica_auditoria = ?, " +
				// "indica_manipulacion_bloques = ?, " +
				// "indica_bloqueo_registros = ?, " +
				// "clave_maximos_errores = ?, " +
				// "clave_maximos_dias = ?, " +
				// "clave_min_dias_reusar = ?, " +
				// "clave_min_cambios_reuso = ?, " +

				"usuario_modifica = ?, terminal_modifica = ? "
				+ "where codigo = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);

		ps.setString(1, userGroup.getName().toUpperCase());
		ps.setString(2, userGroup.getDescription().toUpperCase());
		// ps.setString(3, userGroup.getEffectiveFrom());
		// ps.setString(4, userGroup.getEffectiveUntil());
		// ps.setString(5, userGroup.getUse().toUpperCase());
		// ps.setString(6, userGroup.getAdminCtrlInd().toUpperCase());
		// ps.setString(7, userGroup.getAuditCtrlInd().toUpperCase());
		// ps.setString(8, userGroup.getBlockCtrlInd().toUpperCase());
		// / ps.setString(9, userGroup.getRecLockInd().toUpperCase());
		/*
		 * if(userGroup.getKeyMaxErr()!=null) { ps.setLong(10,
		 * userGroup.getKeyMaxErr().longValue()); } else {
		 * ps.setNull(10,Types.NUMERIC); } if(userGroup.getKeyMaxDays()!=null) {
		 * ps.setLong(11, userGroup.getKeyMaxDays().longValue()); } else {
		 * ps.setNull(11,Types.NUMERIC); }
		 * if(userGroup.getKeyMinDaysReuse()!=null) { ps.setLong(12,
		 * userGroup.getKeyMinDaysReuse().longValue()); } else {
		 * ps.setNull(12,Types.NUMERIC); }
		 * if(userGroup.getKeyMinChangesReuse()!=null) { ps.setLong(13,
		 * userGroup.getKeyMinChangesReuse().longValue()); } else {
		 * ps.setNull(13,Types.NUMERIC); }
		 */
		ps.setString(3, userGroup.getWebUserModif().toUpperCase());
		ps.setString(4, "WEB=" + userGroup.getWebClientModif().toUpperCase());
		ps.setLong(5, userGroup.getCode().longValue());
		int updates = ps.executeUpdate();

		if (updates == 0) {
			return null;
		}

		ps.close();

		return userGroup;

	}

	/**
	 * Borra un registro de la tabla TCS_GRUPO_USUARIO por la llave primaria.
	 * 
	 * @param UserGroupVO
	 *            Value Object con el registro que se va a borrar.
	 * 
	 * @return boolean Indicador de exito de la operacion de borrado
	 */
	public boolean deleteUserGroup(UserGroupVO userGroup) throws SQLException {

		String strSQL = "delete paoyer.tcs_grupo_usuario " + "where codigo = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);
		ps.setLong(1, userGroup.getCode().longValue());
		boolean deletes = ps.execute();
		ps.close();
		return deletes;
	}

}